﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace PES.Common.Extensions
{
    using System;
    using System.Data;

    /// <summary>
    /// Extensões para a classe <see cref="IDataReader"/> utilizada nas leituras de consultas SQL.
    /// </summary>
    public static class DataReaderExtensions
    {
        /// <summary>
        /// Lê um valor do tipo especificado de um DataReader.
        /// </summary>
        /// <typeparam name="T">Tipo do dado a ser lido.</typeparam>
        /// <param name="_reader">Instância de um datareader.</param>
        /// <param name="_columnName">Nome da coluna.</param>
        /// <returns>Instância lida com o tipo especificado, ou o default caso o valor for null.</returns>
        public static T GetValue<T>(this IDataReader _reader, string _columnName)
        {
            return GetValueOrDefault(_reader, _columnName, default(T));
        }

        /// <summary>
        /// Lê um valor do tipo especificado de um DataReader com opção de retorno padrão.
        /// </summary>
        /// <typeparam name="T">Tipo do dado a ser lido.</typeparam>
        /// <param name="_reader">Instância de um datareader.</param>
        /// <param name="_columnName">Nome da coluna.</param>
        /// <param name="_defaultValue">Valor default caso o resultado seja nulo.</param>
        /// <returns>Instância lida com o tipo especificado, ou o default caso o valor for null.</returns>
        public static T GetValueOrDefault<T>(this IDataReader _reader, string _columnName, T _defaultValue)
        {
            return GetValueOrDefault(_reader[_columnName], _defaultValue);
        }

        /// <summary>
        /// Lê um valor do tipo especificado de um DataReader.
        /// </summary>
        /// <typeparam name="T">Tipo do dado a ser lido.</typeparam>
        /// <param name="_reader">Instância de um datareader.</param>
        /// <param name="_index">Índice da coluna.</param>
        /// <returns>Instância lida com o tipo especificado, ou o default caso o valor for null.</returns>
        public static T GetValue<T>(this IDataReader _reader, int _index)
        {
            return GetValueOrDefault(_reader, _index, default(T));
        }

        /// <summary>
        /// Lê um valor do tipo especificado de um DataReader com opção de retorno padrão.
        /// </summary>
        /// <typeparam name="T">Tipo do dado a ser lido.</typeparam>
        /// <param name="_reader">Instância de um datareader.</param>
        /// <param name="_index">Índice da coluna.</param>
        /// <param name="_defaultValue">Valor default caso o resultado seja nulo.</param>
        /// <returns>Instância lida com o tipo especificado, ou o default caso o valor for null.</returns>
        public static T GetValueOrDefault<T>(this IDataReader _reader, int _index, T _defaultValue)
        {
            return GetValueOrDefault(_reader.GetValue(_index), _defaultValue);
        }

        private static T GetValueOrDefault<T>(object _value, T _defaultValue)
        {
            return _value == null || _value is DBNull ? _defaultValue : (T)_value;
        }
    }
}
